package org.carota.itext5;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.carota.pdf.PdfConfigurer;
import org.carota.pdf.PdfProcessor;
import org.carota.vo.MyColor;

import java.io.IOException;

/**
 * @author : AnWen
 * @version :1.0
 * @since : 2023-03-29 18:56
 */
@Slf4j
@NoArgsConstructor
public class WaterMarkConfigurer extends PdfConfigurer {

    /**
     * 水印透明度
     */
    private float opacity;

    /**
     * 字体大小
     */
    private float fontSize;

    /**
     * 水印旋转角度
     */
    private float rotation;

    /**
     * 水印颜色
     */
    private MyColor color;

    /**
     * 水印文字
     */
    private String watermarkText;

    /**
     * 水印类型
     */
    private WatermarkType type;

    /**
     * 字体
     */
    private BaseFont font;

    public enum WatermarkType {
        /**
         * 整页平铺
         */
        TILED,
        /**
         * 一个
         */
        ONLY;

    }


    public WaterMarkConfigurer(PdfProcessor processor) {
        super(processor);
        this.opacity = 0.5f;
        this.fontSize = 30;
        this.rotation = 0;
        this.color = new MyColor (BaseColor.LIGHT_GRAY);
        this.watermarkText = "禁止转载";
        this.type = WatermarkType.ONLY;
        try {
            this.font = BaseFont.createFont ("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        } catch (DocumentException | IOException e) {
            log.error ("初始化字体异常: ",e);
            throw new RuntimeException ("初始化字体异常");
        }


    }

    public WaterMarkConfigurer opacity(float opacity) {
        this.opacity = opacity;
        return this;
    }

    public WaterMarkConfigurer fontSize(float fontSize) {
        this.fontSize = fontSize;
        return this;
    }

    public WaterMarkConfigurer rotation(float rotation) {
        this.rotation = rotation;
        return this;
    }

    public WaterMarkConfigurer color(MyColor color) {
        this.color = color;
        return this;
    }

    public WaterMarkConfigurer watermarkText(String watermarkText) {
        this.watermarkText = watermarkText;
        return this;
    }

    public WaterMarkConfigurer type(WatermarkType type) {
        this.type = type;
        return this;
    }

    public WaterMarkConfigurer font(BaseFont font) {
        this.font = font;
        return this;
    }

    /**
     * 水印
     */
    @Override
    public void execute() {
        PdfStamper stamper = processor.getStamper ();
        PdfReader reader = stamper.getReader ();
        Rectangle pageSize = reader.getPageSizeWithRotation (1);

        for (int i = 1; i <= reader.getNumberOfPages (); i++) {
            PdfContentByte content = stamper.getOverContent (i);
            content.saveState ();
            content.setColorFill (color.getBaseColor ());
            content.setGState (new PdfGState () {{setFillOpacity (opacity);}});
            content.setFontAndSize (font, fontSize);

            if (type.equals (WatermarkType.TILED)) {
                tiled (pageSize, content);
            } else {
                only (content,pageSize.getWidth () / 2, pageSize.getHeight () / 2);
            }
            content.restoreState ();
        }
    }

    /**
     * 校验参数
     */
    @Override
    protected void checkParams() {

    }

    /**
     * 输入坐标
     * @param x
     * @param y
     * @param content
     */
    private void only(PdfContentByte content,float x, float y) {
        content.beginText ();
        content.showTextAligned (Element.ALIGN_CENTER, watermarkText, x, y, rotation);
        content.endText ();
    }

    /**
     * 平铺水印
     * @param pageSize
     * @param content
     */
    private void tiled(Rectangle pageSize, PdfContentByte content) {
        float textWidth = font.getWidthPoint (watermarkText, fontSize);
        float xSpacing = 50; // x轴间距
        float ySpacing = 120; // y轴间距
        float startY = ySpacing / 2;
        float endY = pageSize.getTop () - ySpacing / 2;
        float curX = 60;

        while (curX <= pageSize.getRight ()) {
            float curY = startY;
            while (curY <= endY) {
                float x = curX +  textWidth /2;
                float y = curY - fontSize / 2;
                if (x + textWidth /2  > pageSize.getRight ()) {
                    break;
                }
                only (content,x, y);
                curY += ySpacing;
            }
            curX += xSpacing + textWidth;
        }
    }

    @Override
    public int getOrder() {
        return 20;
    }
}
